import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
from MulSA.Cluster.cluster import *


class PCA:
    def __init__(self):
        self.components = None
        self.eigenvalues = None
        self.eigenvectors = None
        self.new_data = None

    def fit(self, X):
        # 中心化数据
        X_mean = np.mean(X, axis=0)
        X_centered = X - X_mean

        # 标准化数据
        X_std = X_centered / np.std(X, axis=0)

        # 计算协方差矩阵
        cov_matrix = np.cov(X_std, rowvar=False)

        # 计算特征值和特征向量
        eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

        # 对特征值进行排序
        idx = np.argsort(eigenvalues)[::-1]
        self.eigenvalues = eigenvalues[idx]
        self.eigenvectors = eigenvectors[idx]

        # 使用所有的特征向量作为主成分
        self.components = eigenvectors[:, idx]
        self.new_data = np.dot(X_std, self.components)
        # 假设 transformed_data 是你的数据，转换为 DataFrame 并保存到 CSV 文件
        print(self.new_data)
        print(self.eigenvalues)
        df = pd.DataFrame(
            np.concatenate(
                (self.new_data, np.reshape(self.eigenvalues, (1, -1))), axis=0
            )
        )
        df.to_csv("transformed_data.csv", index=False, header=False)
        df = pd.DataFrame(self.eigenvectors)
        df.to_csv("eigenvectors.csv", index=False, header=False)

    def plot_2d(self):
        # 二维可视化展示
        X_transformed = self.new_data
        plt.scatter(X_transformed[:, 0], X_transformed[:, 1])
        # 添加中文标签
        for i in range(len(X_transformed)):
            plt.annotate(
                i + 1, (X_transformed[i, 0], X_transformed[i, 1])
            )  # 替换 '标签' 为你想要显示的中文标签
        plt.xlabel("Principal Component 1")
        plt.ylabel("Principal Component 2")
        plt.title("2D PCA Visualization")
        plt.show()

    def plot_3d(self):
        # 三维可视化展示
        X_transformed = self.new_data
        fig = plt.figure()
        ax = fig.add_subplot(111, projection="3d")
        ax.scatter(
            X_transformed[:, 0],
            X_transformed[:, 1],
            X_transformed[:, 2],
        )
        for i in range(len(X_transformed)):
            ax.text(
                X_transformed[:, 0][i],
                X_transformed[:, 1][i],
                X_transformed[:, 2][i],
                i + 1,
            )  # 替换 '标签' 为你想要显示的文本
        ax.set_xlabel("Principal Component 1")
        ax.set_ylabel("Principal Component 2")
        ax.set_zlabel("Principal Component 3")
        ax.set_title("3D PCA Visualization")
        plt.show()


if __name__ == "__main__":
    X = np.array(
        [
            [90342, 52455, 101091, 19272, 82.0, 16.1, 197435, 0.172],
            [4903, 1973, 2035, 10313, 34.2, 7.1, 592077, 0.003],
            [6735, 21139, 3767, 1780, 36.1, 8.2, 726396, 0.003],
            [49454, 36241, 81557, 22504, 98.1, 25.9, 348226, 0.985],
            [139190, 203505, 215898, 10609, 93.2, 12.6, 139572, 0.628],
            [12215, 16219, 10351, 6382, 62.5, 8.7, 145818, 0.066],
            [2372, 6572, 8103, 12329, 184.4, 22.2, 20921, 0.152],
            [11062, 23078, 54935, 23804, 370.4, 41, 65486, 0.263],
            [17111, 23907, 52108, 21796, 221.5, 21.5, 63806, 0.276],
            [1206, 3930, 6126, 15586, 330.4, 29.5, 1840, 0.437],
            [2150, 5704, 6200, 10870, 184.2, 12, 8913, 0.274],
            [5251, 6155, 10383, 16875, 146.4, 27.5, 78796, 0.151],
            [14341, 13203, 19396, 14691, 94.6, 17.8, 6354, 1.574],
        ]
    )

    pca = PCA()
    pca.fit(X)
    pca.plot_2d()
    pca.plot_3d()
    analysis_all_in_one_2d(pca.new_data[:, :2], 3, save=True)
